﻿<%@ WebHandler Language="C#" Class="WXHandler" %>

using System;
using System.Web;
public class jsapi_ticketClass
{
    public jsapi_ticketClass()
    {
        jsapi_ticket_DateTime = DateTime.Now;
    }

    public string url { get; set; }
    public string jsapi_ticket { get; set; }
    public DateTime jsapi_ticket_DateTime { get; set; }
}
public class jsapi_access_token
{
    public string access_token { get; set; }
    public string expires_in { get; set; } 
}
public class jsapi_access_ticket
{
    public int errcode { get; set; }
    public string errmsg { get; set; }
    public string ticket { get; set; }
    public string expires_in { get; set; }
}
public class jsapi_access_return
{
    public string appId { get; set; }
    public string timestamp { get; set; }
    public string noncestr { get; set; }
    public string signature { get; set; }
}
public class WXHandler : IHttpHandler
{
    public static jsapi_ticketClass jsapi_ticketc = new jsapi_ticketClass();
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        string screct="2316e5b8efec130bc310bc8382983855";
        string appId = "wxf738fe0b7feaa06a";//公众号的唯一标识
        long timestamp = 0;//生成签名的时间戳
        string noncestr = CreatenNonce_str();//生成签名的随机串
        string signature = "";//签名
        string url = ""; 
        url = context.Request.QueryString["url"] == null ? "" : context.Request.QueryString["url"].ToString().Trim();
        getTicketFromWX(appId, screct, url);
        string jsapi_ticket = jsapi_ticketc.jsapi_ticket;
        timestamp = CreatenTimestamp();
        string string1 = "";
        signature = GetSignature(jsapi_ticket, noncestr, timestamp, url, out string1);
        jsapi_access_return jar = new jsapi_access_return();
        if (jsapi_ticket != "")
        {
            jar.appId = appId;
            jar.timestamp = timestamp.ToString() ;
            jar.noncestr = noncestr;
            jar.signature = signature;
        }
        using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
        {
            System.Runtime.Serialization.Json.DataContractJsonSerializer json = new System.Runtime.Serialization.Json.DataContractJsonSerializer(jar.GetType());
            json.WriteObject(stream, jar);
            string szJson = System.Text.Encoding.UTF8.GetString(stream.ToArray());
            context.Response.Write(szJson);
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
    
    /// <summary>
    /// 创建时间戳 
    /// </summary>
    /// <returns></returns>
    public static long CreatenTimestamp()
    {
        return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
    }
    public void getTicketFromWX(string appId, string secret, string _url)
    {
        string result = "";
        DateTime dtn = DateTime.Now;
        DateTime dtt = jsapi_ticketc.jsapi_ticket_DateTime; 
        if (dtn>dtt.AddMinutes(-10)||jsapi_ticketc.url!=_url)
        try
        {
            string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
            result = GetFromWXJSAPI(url);
            jsapi_access_token jatoken = new jsapi_access_token();
            jsapi_access_ticket jaticket = new jsapi_access_ticket();
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(result)))
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(jsapi_access_token));
                jatoken = (jsapi_access_token)serializer.ReadObject(ms);
                url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + jatoken.access_token + "&type=jsapi";
                result = GetFromWXJSAPI( url);
                using (System.IO.MemoryStream ms1 = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(result)))
                {
                    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer1 = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(jsapi_access_ticket));
                    jaticket = (jsapi_access_ticket)serializer1.ReadObject(ms1);
                    jsapi_ticketc.jsapi_ticket = jaticket.ticket;
                    jsapi_ticketc.jsapi_ticket_DateTime = DateTime.Now.AddSeconds(7200);
                    jsapi_ticketc.url = _url;
                }
                
            }
            
            
        }
        catch (Exception ex)
        {
            jsapi_ticketc.jsapi_ticket = "";
            jsapi_ticketc.jsapi_ticket_DateTime = DateTime.Now;
        }
       
    }

    private static string GetFromWXJSAPI( string url)
    {
        string result = "";
        System.Net.HttpWebRequest httpRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
        httpRequest.Timeout = 2000;
        httpRequest.Method = "GET";
        System.Net.HttpWebResponse httpResponse = (System.Net.HttpWebResponse)httpRequest.GetResponse();
        System.IO.StreamReader sr = new System.IO.StreamReader(httpResponse.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"));
        result = sr.ReadToEnd();
        result = result.Replace("\r", "").Replace("\n", "").Replace("\t", "");
        int status = (int)httpResponse.StatusCode;
        sr.Close();
        return result;
    }

    
    /// <summary>
    /// 创建随机字符串 
    /// </summary>
    /// <returns></returns>
    public static string CreatenNonce_str()
    {
         string[] strs = new string[]
                                 {
                                  "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
                                  "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
                                 };
        Random r = new Random();
        var sb = new System.Text.StringBuilder();
        var length = strs.Length;
        for (int i = 0; i < 15; i++)
        {
            sb.Append(strs[r.Next(length - 1)]);
        }
        return sb.ToString();
    }
    /// <summary>
    /// 签名算法 
    /// </summary>
    /// <param name="jsapi_ticket">jsapi_ticket</param>
    /// <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
    /// <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
    /// <param name="url">当前网页的URL，不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
    /// <returns></returns>
    public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string string1)
    {
        var string1Builder = new System.Text.StringBuilder();
        string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                      .Append("noncestr=").Append(noncestr).Append("&")
                      .Append("timestamp=").Append(timestamp).Append("&")
                      .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
        string1 = string1Builder.ToString();
        return  Sha1(string1);
    }
    /// <summary>
    /// Sha1
    /// </summary>
    /// <param name="orgStr"></param>
    /// <param name="encode"></param>
    /// <returns></returns>
    public static string Sha1(string orgStr, string encode = "UTF-8")
    {
        var sha1 = new System.Security.Cryptography.SHA1Managed();
        var sha1bytes = System.Text.Encoding.GetEncoding(encode).GetBytes(orgStr);
        byte[] resultHash = sha1.ComputeHash(sha1bytes);
        string sha1String = BitConverter.ToString(resultHash).ToLower();
        sha1String = sha1String.Replace("-", "");
        return sha1String;
    }
}
